package org.example.demo;

import cn.hutool.core.bean.BeanUtil;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class Snake {
    private Integer length;
    private List<Point> pointList = new ArrayList<>();
    private Direction direction = Direction.R;
    private Point randomPoint;

    private ImageIcon head = new ImageIcon(Resource.class.getClassLoader().getResource("black.jpg"));
    private ImageIcon body = new ImageIcon(Resource.class.getClassLoader().getResource("white.jpg"));
    private ImageIcon random = new ImageIcon(Resource.class.getClassLoader().getResource("red.jpg"));

    public Snake() {
        init();
    }

    public void init(){
        length = 3;
        int x = 100;
        int y = 100;
        for (int i = 0; i < 3; i++) {
            pointList.add(new Point(x, y));
            x-=25;
        }

        reSetRandomPoint();
    }

    public void reSetRandomPoint(){
        int xRandom = ThreadLocalRandom.current().nextInt(5,10);
        int yRandom = ThreadLocalRandom.current().nextInt(5,10);

        randomPoint = new Point(xRandom * 25, yRandom * 25);
    }

    public void paint(Component c,Graphics g){
        head.paintIcon(c,g,(int)pointList.get(0).getX(),(int)pointList.get(0).getY());
        pointList.stream().skip(1).forEach(point -> body.paintIcon(c,g,point.x,point.y));
        random.paintIcon(c,g, randomPoint.x, randomPoint.y);

    }

    public void go() throws GameOverException {
        Point tmp = new Point();
        BeanUtil.copyProperties(pointList.get(0), tmp);
        switch (direction) {
            case R:
                Point point = new Point(pointList.get(0).x += 25, pointList.get(0).y);
                if (point.x >= 900){
                    point.x = 50;
                }
                pointList.set(0,point);
                break;
            case L:
                Point pointL = new Point(pointList.get(0).x -= 25, pointList.get(0).y);
                if (pointL.x <= 0){
                    pointL.x = 900;
                }
                pointList.set(0,pointL);
                break;
            case D:
                Point pointD = new Point(pointList.get(0).x, pointList.get(0).y += 25);
                if (pointD.y >= 850){
                    pointD.y = 100;
                }
                pointList.set(0,pointD);
                break;
            case U:
                Point pointU = new Point(pointList.get(0).x, pointList.get(0).y -= 25);
                if (pointU.y <= 100){
                    pointU.y = 850;
                }
                pointList.set(0,pointU);
                break;
            default:
                break;
        }
        if (pointList.stream().skip(1).anyMatch(point -> point.equals(pointList.get(0)))){ // 撞到自己了
            throw new GameOverException("游戏结束");
        }

        for (int i = 1; i < pointList.size(); i++) {
            Point tmpp = pointList.get(i);
            pointList.set(i,tmp);
            tmp = tmpp;
        }

        if (pointList.get(0).equals(randomPoint)){ // 吃到点了
            pointList.add(tmp);
            reSetRandomPoint();
        }

    }

    public void changeDir(Direction direction){
        if (this.direction.equals(direction)){
            return;
        }
        if (this.direction.isMutex(direction)){
            return;
        }
        this.direction = direction;
    }
}
